#include "Stdafx.h"
#include "Value.h"

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace SNMP;

Value::Value(void)
{
	this->m_bytEmpty = 0;
	this->m_intNumber = 0;
	this->m_lngNumber = 0;
	this->m_objData = gcnew Object();
	this->m_strOid = System::String::Empty;
}

Value::Value(Syntax syntax, Object^ value)
{
	this->m_objData = value;
	this->m_Syntax = syntax;
	this->m_bytEmpty = 0;
	this->m_intNumber = 0;
	this->m_lngNumber = 0;
	this->m_strOid = value == nullptr ? String::Empty : value->ToString();
	this->m_strString = value == nullptr ? String::Empty : value->ToString();
	this->m_ulngNumber = 0;

	byte::TryParse(value->ToString(), this->m_bytEmpty);
	int::TryParse(value->ToString(), this->m_intNumber);
	INT64::TryParse(value->ToString(), this->m_lngNumber);
}

Value^ Value::SNMPValueToValue(smiVALUE value)
{
	Value^ retValue = gcnew Value();
	retValue->m_bytEmpty = value.value.empty;
	retValue->m_intNumber = value.value.sNumber;
	//retValue->m_lngNumber = value.value.hNumber;
	retValue->m_strOid = Helper::ToString(value.value.oid);
	retValue->m_strString = Helper::ToString( value.value.string);
	retValue->m_strIpAddress = Helper::ToIpAddress( value.value.string);
	retValue->m_ulngNumber = value.value.uNumber;
	Value::ConvertSyntax(value.syntax, retValue);
	return retValue;
}

void Value::ConvertSyntax(smiUINT32 syntax, Value^ value)
{
	switch (syntax)
	{
	case SNMP_SYNTAX_CNTR32:
		//value->m_objData = value->m_bytEmpty;
		value->m_Syntax = Syntax::Cntr32;
		break;
	case SNMP_SYNTAX_CNTR64:
		//value->m_objData = value->m_bytEmpty;
		value->m_Syntax = Syntax::Cntr64;
		break;
	case SNMP_SYNTAX_ENDOFMIBVIEW:
		//value->m_objData = value->m_bytEmpty;
		value->m_Syntax = Syntax::EndOfMibView;
		break;
	case SNMP_SYNTAX_GAUGE32:
		value->m_objData = value->m_intNumber;
		value->m_Syntax = Syntax::Gauge32;
		break;
	case SNMP_SYNTAX_INT:
		value->m_objData = value->m_intNumber;
		value->m_Syntax = Syntax::Integer;
		break;
		//case SNMP_SYNTAX_INT32:
		//value->m_objData = value->m_bytEmpty;
		//value->m_Syntax = Syntax::Integer32;
		//break;
	case SNMP_SYNTAX_IPADDR:
		value->m_objData = value->m_strIpAddress;
		value->m_Syntax = Syntax::IPAddress;
		break;
	case	SNMP_SYNTAX_NOSUCHINSTANCE:
		//value->m_objData = value->m_bytEmpty;
		value->m_Syntax = Syntax::NoSuchInstance;
		break;
	case SNMP_SYNTAX_NOSUCHOBJECT:
		//value->m_objData = value->m_bytEmpty;
		value->m_Syntax = Syntax::NoSuchObject;
		break;
	case SNMP_SYNTAX_NULL:
		//value->m_objData = value->m_bytEmpty;
		value->m_Syntax = Syntax::Null;
		break;
	case SNMP_SYNTAX_OCTETS:
		value->m_objData = value->m_strString;
		value->m_Syntax = Syntax::Octets;
		break;
	case SNMP_SYNTAX_OID:
		value->m_objData = value->m_strOid;
		value->m_Syntax = Syntax::Oid;
		break;
	case SNMP_SYNTAX_OPAQUE:
		//value->m_objData = value->m_bytEmpty;
		value->m_Syntax = Syntax::Opaque;
		break;
	case SNMP_SYNTAX_TIMETICKS:
		value->m_objData = (unsigned int)value->m_intNumber;
		value->m_Syntax = Syntax::Timeticks;
		break;
	case SNMP_SYNTAX_UINT32:
		//value->m_objData = value->m_bytEmpty;
		value->m_Syntax = Syntax::UnsignedInteger32;
		break;
	default:
		value->m_objData =nullptr;
		value->m_Syntax = Syntax::Null;
		break;
	}
}


smiVALUE Value::ValueToSNMPValue(Value^ value)
{
	ObjectToValue(value->m_objData, value);
	smiVALUE retValue;
	Value::ConvertSyntax(value->m_Syntax, &retValue, value);
	//retValue.value.empty = value->m_bytEmpty;
	//retValue.value.sNumber= value->m_intNumber;
	// retValue.value.hNumber = value->m_lngNumber
	//retValue.value.oid.len = NULL;
	//retValue.value.oid.ptr = NULL;
	//retValue.value.string.len = NULL;
	//retValue.value.string.ptr = NULL;
	//retValue.value.uNumber = value->m_ulngNumber;
	//if(value->m_Syntax == Syntax::Octets)
	//{
		//retValue.value.string = Helper::ToOctets(value->m_strString);
	//}
	return retValue;
}

void Value::ConvertSyntax(Syntax syntax, smiVALUE* value, Value^ oldData)
{
	switch (syntax)
	{
	case Syntax::Cntr32:
		value->syntax = SNMP_SYNTAX_CNTR32;
		break;
	case Syntax::Cntr64:
		value->syntax = SNMP_SYNTAX_CNTR64;
		break;
	case Syntax::EndOfMibView:
		value->syntax = SNMP_SYNTAX_ENDOFMIBVIEW;
		break;
	case Syntax::Gauge32:
		value->syntax = SNMP_SYNTAX_GAUGE32;
		value->value.sNumber = oldData->m_intNumber;
		break;
	case Syntax::Integer:
		value->syntax = SNMP_SYNTAX_INT;
		value->value.sNumber = oldData->m_intNumber;
		break;
	case Syntax::Integer32:
		value->syntax = SNMP_SYNTAX_INT32;
		value->value.sNumber = oldData->m_intNumber;
		break;
	case Syntax::IPAddress:
		value->syntax = SNMP_SYNTAX_IPADDR;
		break;
	case Syntax::NoSuchInstance:
		value->syntax = SNMP_SYNTAX_NOSUCHINSTANCE;
		break;
	case Syntax::NoSuchObject:
		value->syntax = SNMP_SYNTAX_NOSUCHOBJECT;
		break;
	case Syntax::Null:
		value->syntax = SNMP_SYNTAX_NULL;
		break;
	case Syntax::Octets:
		value->syntax = SNMP_SYNTAX_OCTETS;
		value->value.string = Helper::ToOctets(oldData->m_strString);
		break;
	case Syntax::Oid:
		value->syntax = SNMP_SYNTAX_OID;
		value->value.oid = Helper::ToOID(oldData->m_strOid);
		break;
	case Syntax::Opaque:
		value->syntax = SNMP_SYNTAX_OPAQUE;
		break;
	case Syntax::Timeticks:
		value->syntax = SNMP_SYNTAX_TIMETICKS;
		value->value.uNumber = (unsigned int)oldData->m_intNumber;
		break;
	case Syntax::UnsignedInteger32:
		value->syntax = SNMP_SYNTAX_UINT32;
		break;
	default:
		value->syntax = SNMP_SYNTAX_NULL;
		break;
	}
}

void Value::ObjectToValue(Object^ srcValue, Value^ dstValue)
{
	if(srcValue == nullptr)
	{
		dstValue->m_bytEmpty = 0;
		dstValue->m_intNumber = 0;
		dstValue->m_lngNumber = 0;
		dstValue->m_strOid = String::Empty;
		dstValue->m_strString = String::Empty;
		dstValue->m_ulngNumber = 0;
	}
	else
	{
		byte::TryParse(srcValue->ToString(), dstValue->m_bytEmpty);
		int::TryParse(srcValue->ToString(), dstValue->m_intNumber);
		INT64::TryParse(srcValue->ToString(), dstValue->m_lngNumber);
		dstValue->m_strOid = srcValue->ToString();
		dstValue->m_strString =srcValue->ToString();
		//dstValue->m_ulngNumber = (unsigned long)srcValue;
	}
}
